import { _decorator, Sprite, Node, UITransform, tween, IVec2, Vec3, Tween, Color } from 'cc';
import { EntityTypeEnum, StateTypeEnum } from '../../Common';
import { IEnemy } from '../../Common/Interface/State';
import { createUINode } from '../../Utils';
import { EntityManager } from '../../Base/EntityManager';
import { EnemyStateMachine } from './EnemyStateMachine';
import { ObjectPoolManager } from '../../Runtime/ObjectPoolManager';
import DataManager from '../../Runtime/DataManager';
import { addLabel, castingTimeEffect, flash } from '../../Runtime/MainManager';
import { GameLogic } from '../../Common/Runtime/GameLogic';
import ResourcesManager from '../../Runtime/ResourcesManager';
import { MaterialEnum } from '../../Enum';
const { ccclass, property } = _decorator;

@ccclass('EnemyManager')
export class EnemyManager extends EntityManager {

    id: number

    body: Node
    agentId: number
    tw: Tween<Node>
    playingDieAnim = false

    init(data: IEnemy) {
        this.type = data.type

        this.body = createUINode('body')
        this.body.parent = this.node
        const sprite = this.body.addComponent(Sprite)
        sprite.trim = false
        sprite.sizeMode = Sprite.SizeMode.CUSTOM
        const size = GameLogic.Ins.getEntitySizeByType(this.type)
        this.body.getComponent(UITransform).setContentSize(size.w, size.h)
        sprite.customMaterial = ResourcesManager.Ins.materialMap.get(MaterialEnum.entityMaterial)

        this.fsm = this.addComponent(EnemyStateMachine)
        this.fsm.init(this)

    }

    reset(data: IEnemy) {
        const {
            id,
            type,
            agentId,
        } = data

        this.agentId = agentId
        this.type = type
        this.id = id

        this.node.setScale(1, 1)
        this.node.setRotationFromEuler(0, 0, 0)
        this.body.getComponent(Sprite).color = Color.WHITE

    }
    enemyDie({ x, y }: IVec2) {
        this.playingDieAnim = true
        this.state = StateTypeEnum.none
        tween(this.node)
            .by(0.5, { position: new Vec3(x * 100, y * 100), scale: new Vec3(-1, -1), angle: 1440 })
            .call(() => {
                this.playingDieAnim = false
                ObjectPoolManager.Ins.poolFree(this)
                DataManager.Ins.enemyMap.delete(this.id)
            })
            .start()
    }
    render(data: IEnemy) {
        if (this.playingDieAnim) {
            return
        }
        const {
            position: { x, y },
            direction,
            state,
            isBeHit,
            recoverHP
        } = data

        this.body.setScale(direction.x > 0 ? 1 : -1, 1)

        this.node.setPosition(x, y)
        if (state === StateTypeEnum.dead) {
            this.enemyDie(direction)
        } else if (state === StateTypeEnum.castingTime) {
            castingTimeEffect(this.body)
        } else if (state === StateTypeEnum.standCastingTime) {
            if (this.state !== StateTypeEnum.none) {
                this.state = StateTypeEnum.none
                castingTimeEffect(this.body)
            }
        } else if (state === StateTypeEnum.impact) {
            this.state = StateTypeEnum.none
            if (isBeHit === 1) {
                flash(this.body)
            }
        } else if (isBeHit === 1) {
            flash(this.body)
        } else {
            this.state = state
        }
        if (recoverHP && recoverHP > 0) {
            addLabel('+' + recoverHP, EntityTypeEnum.fontGreen, { x, y })
        }

    }
}